﻿namespace SmartMotion.Core
{
    /// <summary>
    /// 轴的基类，他的子类可能有板卡轴，机械手的轴，PLC带的轴…………
    /// 单轴的属性和行为
    /// </summary>
    public abstract class AxisBase : BindableBase
    {
        private string _axisName;

        public AxisBase()
        {

        }
        protected AxisBase(ushort cardID, ushort axisID)
        {
            CardID = cardID;
            AxisID = axisID;
        }

        #region 属性

        public string AxisName
        {
            get { return _axisName; }
            set { SetProperty(ref _axisName, value); }
        }
        public AxisDirection AxisDirection { get; set; }
        public ushort AxisID { get; set; }
        public ushort CardID { get; set; }

        public double Equiv { get; set; }

        public double MinVel { get; set; }

        public double MaxVel { get; set; }
        public double MaxAcc { get; set; }

        public double MaxDec { get; set; }

        public double StopVel { get; set; }

        public double  SpeedRate { get; set; }
        #endregion


        #region 常用功能

        //轴初始化
        //轴使能 On
        //轴失能 Off
        //设置轴参数
        //获取轴参数
        //设置正负方向的软限位
        //设置速度
        //获取速度
        //移动到指定位置，相对运动
        //移动到指定位置，绝对运动
        //是否运动到指定位置
        //获取当前位置（指令位置，编码器位置，光栅尺位置）
        //Jog运动，匀速运动
        //急停
        //减速停，平滑停止
        //获取状态
        //清除报警
        //是否运动中
        //是否达到正限位
        //是否到达负限位
        //驱动器报警
        //原点信号
        //急停信号
        //Home
        //回零状态
        //回零是否完成
        //清除位置（指令位置，编码器位置）
        //扭矩运动
        //PVT运动，point v torque
        //

        #endregion 常用功能
            
        //Step2
        /// <summary>
        /// 脉冲当量，多少脉冲对应1mm
        /// </summary>
        /// <param name="equiv">脉冲当量</param>
        /// <returns></returns>
        public abstract int SetEquiv(double equiv);

        /// <summary>
        /// 获取脉冲当量
        /// </summary>
        /// <param name="equiv"></param>
        /// <returns></returns>
        public abstract int GetEquiv(out double equiv);

        //Step3
        /// <summary>
        /// 停止单轴
        /// </summary>
        /// <param name="stopMode">0是减速停止，1是急停</param>
        /// <returns></returns>
        public abstract int Stop(ushort stopMode);

        //Step4
        /// <summary>
        /// 轴使能
        /// </summary>
        /// <returns></returns> 
        public abstract int AxisEnable();

        /// <summary>
        /// 关掉使能
        /// </summary>
        /// <returns></returns>
        public abstract int AxisDisable();

        //Step5
        //nmc_set_home_profile 设置 EtherCAT 总线轴回零参数
        //nmc_get_home_profile 读取 EtherCAT 总线轴回零参数
        //nmc_home_move 启动 EtherCAT 总线轴回零
        //dmc_get_home_result 读取回零状态
        /// <summary>
        /// 设置回零参数
        /// </summary>
        /// <param name="homeMode"></param>
        /// <param name="lowVel"></param>
        /// <param name="highVel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="offsetPos"></param>
        /// <returns></returns>
        public abstract int SetHomeParms(ushort homeMode, double lowVel, double highVel, double acc, double dec, double offsetPos);

        /// <summary>
        /// 读取回零参数
        /// </summary>
        /// <param name="homeMode"></param>
        /// <param name="lowVel"></param>
        /// <param name="highVel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="offsetPos"></param>
        /// <returns></returns>
        public abstract int GetHomeParms(out ushort homeMode, out double lowVel, out double highVel, out double acc, out double dec, out double offsetPos);

        /// <summary>
        /// 开始回零
        /// </summary>

        /// <returns></returns>
        public abstract int HomeMove();

        /// <summary>
        /// 获取回零结果
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        public abstract int GetHomeResult(out ushort state);

        //Step6,

        public abstract int SetSpeed(double minVel, double maxVel, double acc, double dec, double stopVel);

        public abstract int SetSpeed(Speed speed);

        public abstract int SetSpeed(double rate);//推荐，速度比例

        public abstract int GetSpeed(out double minVel, out double maxVel, out double acc, out double dec, out double stopVel);

        public abstract int GetSpeed(out Speed speed);

        public abstract int GetSpeed(out double rate);//推荐，速度比例

        /// <summary>
        /// 点位运动,PMove,VMove,TMove
        /// </summary>
        /// <param name="dist"></param>
        /// <param name="posiMode">定位模式，相对运动和绝对运动</param>
        /// <returns></returns>
        public abstract int Move(double dist, ushort posiMode);

        /// <summary>
        /// 检查轴运动完成
        /// </summary>
        /// <returns></returns>
        public abstract int CheckDone();

        /// <summary>
        /// 匀速运动
        /// </summary>
        /// <param name="dir">方向</param>
        /// <returns></returns>
        public abstract int VMove(ushort dir);

        /// <summary>
        /// 扭矩运动
        /// </summary>
        /// <param name="torque"></param>
        /// <param name="maxSpeed"></param>
        /// <returns></returns>
        // ReSharper disable once InconsistentNaming
        public abstract int TMove(double torque, double maxSpeed);
    }

    public enum SymbleDirection
    {
        Left = 61536,
        Right = 61537,
        Forword = 61538,
        Backword = 61539,
        Up = 361793,
        Down = 363620,
        Clockwise = 361470,
        Counterclockwise = 361666
    }

    public enum AxisDirection
    {
        LeftRight,
        ForBackword,
        UpDn,
        Rotate,
    }
}